package com.oly.cms.admin.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.oly.cms.admin.mapper.CmsCategoryMapper;
import com.oly.cms.admin.service.ICmsCategoryService;
import com.oly.cms.common.constant.CmsCacheConstant;
import com.oly.cms.common.domain.VisibleParam;
import com.oly.cms.common.domain.entity.CmsCategory;
import com.oly.cms.common.event.CacheWebRefreshAllEvent;
import com.oly.cms.common.model.enums.IsRootEnums;
import com.oly.cms.common.model.properties.OlyCmsConfigProperties;
import com.oly.cms.general.mapper.CategorySearchMapper;
import com.grace.common.constant.UserConstants;
import com.grace.common.exception.ServiceException;
import com.grace.system.service.impl.SysSearchConfigServiceImpl;

@Service
public class CmsCategoryServiceImpl implements ICmsCategoryService {

    @Autowired
    private CmsCategoryMapper cmsCatMapper;

    @Autowired
    private CategorySearchMapper categorySearchMapper;

    @Autowired
    private SysSearchConfigServiceImpl configService;

    @Autowired
    private ApplicationEventPublisher app;

    @Override
    public int insertCmsCat(CmsCategory cmsCategory) {
        if (!checkCatUnique(cmsCategory, false)) {
            throw new ServiceException("请检查路径或者分类名是否重复");
        } else if (cmsCategory.getParentId() == 0) {
            cmsCategory.setAncestors("0");
        } else {
            CmsCategory ca = categorySearchMapper.selectCmsCatById(cmsCategory.getParentId());
            if (ca == null || ca.getParent() == IsRootEnums.NO.ordinal()) {
                throw new ServiceException("插入点不存在,或者插入点非根节点");
            } else {
                cmsCategory.setAncestors(ca.getAncestors() + "," + cmsCategory.getParentId());
            }
        }
        int re = cmsCatMapper.insertCmsCat(cmsCategory);
        app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATS_CACHE_KEY_PREFIX));
        return re;
    }

    @Override
    @Transactional
    public int updateCmsCat(CmsCategory cmsCategory) {
        if (cmsCategory.getCatId().longValue() == cmsCategory.getParentId().longValue()) {
            throw new ServiceException("不能选择自己作为父节点");
        } else if (IsRootEnums.NO.ordinal() == cmsCategory.getParent()
                && !this.checkCatUnique(cmsCategory, true)) {
            throw new ServiceException("存在子节点不允许修改节点类型");
        } else if (!checkCatUnique(cmsCategory, false)) {
            throw new ServiceException("请检查路径或者分类名是否重复");
        } else if (cmsCategory.getParentId().longValue() == 0) {
            cmsCategory.setAncestors("0");
        } else {
            CmsCategory ca = categorySearchMapper.selectCmsCatById(cmsCategory.getParentId());
            // 非目录不允许插入
            if (ca == null || ca.getParent() == IsRootEnums.NO.ordinal()) {
                throw new ServiceException("插入点不存在,或者插入点目录节点");
            } else {
                cmsCategory.setAncestors(ca.getAncestors() + "," + cmsCategory.getParentId());
            }
        }
        int c = cmsCatMapper.updateCmsCat(cmsCategory);
        // 同时更新子节点
        CmsCategory childCategory = new CmsCategory();
        childCategory.setParentId(cmsCategory.getCatId());
        childCategory.setUpdateBy(cmsCategory.getUpdateBy());
        childCategory.setAncestors(cmsCategory.getAncestors() + "," + cmsCategory.getCatId());
        updateChildNode(childCategory);
        updateChildCatVisible(cmsCategory);
        app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATS_CACHE_KEY_PREFIX));
        return c;

    }

    @Override
    public int updateChildCatVisible(CmsCategory cmsCategory) {
        int re = 0;
        if ("true".equals(configService.selectConfigDefaultValue(OlyCmsConfigProperties.CMS_CONFIG_GROUP.defaultValue(),
                OlyCmsConfigProperties.CATEGORY_UPDATE_CHILD))) {
            re = cmsCatMapper.updateChildCatVisible(cmsCategory);
        }
        app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATS_CACHE_KEY_PREFIX));
        return re;
    }

    @Override
    public int deleteCmsCatById(Long catId) {
        CmsCategory cmsCat = new CmsCategory();
        cmsCat.setParentId(catId);
        if (!this.checkCatUnique(cmsCat, true)) {
            throw new ServiceException("存在子节点不允许删除");
        }
        if (cmsCatMapper.countArticleByCatId(catId) > 0) {
            throw new ServiceException("与文章有关联不允许删除");
        }
        int re = cmsCatMapper.deleteCmsCatById(catId);
        app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATS_CACHE_KEY_PREFIX));
        return re;
    }

    @Override
    public List<CmsCategory> listCmsCatByCat(CmsCategory CmsCategory) {
        return categorySearchMapper.listCmsCats(CmsCategory);
    }

    @Override
    public CmsCategory selectCmsCatById(long catId) {
        return categorySearchMapper.selectCmsCatById(catId);
    }

    /**
     * 可用于验证
     * 分类名
     * 分类路径
     * 是否存在子节点
     * 
     */
    @Override
    public boolean checkCatUnique(CmsCategory cmsCategory, boolean node) {
        CmsCategory gf = null;
        if (node) {
            gf = new CmsCategory();
            gf.setParentId(cmsCategory.getCatId());
        } else {
            gf = cmsCategory;
        }
        Long catId = cmsCategory.getCatId() == null ? -1L : cmsCategory.getCatId();
        CmsCategory checkCat = categorySearchMapper.checkCatUnique(gf);
        if (checkCat == null || checkCat.getCatId().longValue() == catId) {
            return UserConstants.UNIQUE;
        }
        return UserConstants.NOT_UNIQUE;
    }

    @Override
    public int countArticleByCatId(Long catId) {
        return cmsCatMapper.countArticleByCatId(catId);
    }

    @Override
    public List<CmsCategory> listCmsCatByArticleId(VisibleParam vParam) {
        return categorySearchMapper.listCmsCatByArticleId(vParam);
    }

    private void updateChildNode(CmsCategory cmsCategory) {
        if (updateChildCatAncestors(cmsCategory) > 0) {
            List<Long> lis = parentIds(cmsCategory.getParentId());
            if (lis != null) {
                for (int i = 0; i < lis.size(); i++) {
                    cmsCategory.setParentId(lis.get(i));
                    cmsCategory.setAncestors(cmsCategory.getAncestors() + "," + lis.get(i));
                    updateChildNode(cmsCategory);
                }
            }
        }
    }

    /**
     * 根据父亲Id修改Ancestors 根据父亲Id获取子元素子节点，循环遍历
     * 
     * @param catId
     * @return
     */
    private List<Long> parentIds(long parentId) {
        return cmsCatMapper.listCatIdsById(parentId);
    }

    private int updateChildCatAncestors(CmsCategory cmsCategory) {
        return cmsCatMapper.updateChildCatAncestors(cmsCategory);
    }

}
